
#ifndef SENGEN_H_
#define SENGEN_H_

#include "Default.h"
#include "Deptree.h"
#include "CGRNN.h"
#include "Matrix.h"
#include <vector>
#include <map>

using namespace std;

struct STATE {
	int headnode;
	int lastnode;
	int genstate;

	Matrix* inputHead_Left;
	Matrix* inputHead_Right;
	Matrix* inputHead_Left_p;
	Matrix* inputHead_Right_p;
	Matrix* priorRep;
	vector<Matrix*> hiProds;

	STATE(int iheadnode, int ilastnode, int igenstate, Matrix* iinputHead_Left,
			Matrix* iinputHead_Right, Matrix* iinputHead_Left_p, Matrix* iinputHead_Right_p,
			Matrix* ipriorRep, vector<Matrix*> &ihiProds) {
		headnode = iheadnode;
		lastnode = ilastnode;
		genstate = igenstate;

		inputHead_Left = iinputHead_Left;
		inputHead_Right = iinputHead_Right;
		inputHead_Left_p = iinputHead_Left_p;
		inputHead_Right_p = iinputHead_Right_p;
		priorRep = ipriorRep;
		hiProds = ihiProds;
	}

	~STATE() {
		if (inputHead_Left != NULL) delete inputHead_Left;
		if (inputHead_Right != NULL) delete inputHead_Right;
		if (inputHead_Left_p != NULL) delete inputHead_Left_p;
		if (inputHead_Right_p != NULL) delete inputHead_Right_p;
		if (priorRep != NULL) delete priorRep;
		for (Matrix* m : hiProds)
			delete m;
	}
};

typedef std::map< real,pair<Deptree*,STATE*>, std::greater<real> > AGENDA;

class SenGenerator {
public:

	SenGenerator() {}
	virtual ~SenGenerator() {}

	void genDeprel(CGRNN* net, Matrix* rep, int k, vector< pair<real,int> >& ret);
	void genPos(CGRNN* net, Matrix* rep, int deprel, int k, vector< pair<real,int> > &ret);
	void genWord(CGRNN* net, Matrix* rep, int pos, int deprel, int k, vector< pair<real,int> > &ret);

	void genLeftDep(CGRNN* net, Deptree* tree, real score, STATE *state, AGENDA& ret, int expectedLength);
	void genRightDep(CGRNN* net, Deptree* tree, real score, STATE *state, AGENDA& ret, int expectedLength);
	bool genDep(CGRNN* net, Deptree* tree, real score, STATE *state, AGENDA& ret, int expectedLength);
	real lengthPenalty(int lenght, int expectedLength);

	void generate(CGRNN* net, Matrix* rootRep, int expectedLength, vector<pair<real,Deptree*>> &sorted);
};

#endif // def
